using UnityEngine;

public class ReturnBallDemo : MonoBehaviour
{
	[Range(0.02f, 1f)]
	public float timeScale = 1f;

	public bool instantMove;

	public HitAnimationsStateEnum hitAnimEnum;

	public BallHitTest hitTest;

	public PhysicsBall ball;

	public Transform start;

	public Vector3 realHitPoint;

	public Vector3 calculatedHitPoint;

	public Transform racketCenter;

	private Vector3 prevRacketCenter;

	private float prevTime;

	protected KineticPlan kineticPlan
	{
		get
		{
			return GetComponent<KineticPlan>();
		}
	}

	public HitAnimationInfo hitAnim
	{
		get
		{
			return ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateHitAnimationByEnum(hitAnimEnum);
		}
	}

	public void HitBall(Vector3 hitPosition, Vector3 hitVelocity, float timeSinceHit)
	{
		FlightParams startParams = default(FlightParams);
		startParams.velocity = hitVelocity;
		startParams.angularVelocity = Vector3.zero;
		startParams.position = hitPosition;
		FlightSimulator instance = Singleton<FlightSimulator>.instance;
		FlightSimulator.SequenceSimulationParams sequenceSimulationParams = default(FlightSimulator.SequenceSimulationParams);
		sequenceSimulationParams.startParams = startParams;
		sequenceSimulationParams.flightToSymulateWith = hitTest.GetUsedBallFlight();
		sequenceSimulationParams.deltaTime = hitTest.symDeltaTime;
		sequenceSimulationParams.record = true;
		sequenceSimulationParams.maxHops = 3;
		sequenceSimulationParams.maxIterations = 100;
		FlightSimulator.SequenceSimulationParams sim = sequenceSimulationParams;
		ball.position = hitPosition;
		ball.flightSequence.Reset();
		instance.FillFlightSequence(ball.flightSequence, sim);
		ball.flightSequence.Reset();
		ball.flightSequence.Update(timeSinceHit);
	}

	public void LaunchBall()
	{
		FlightParams initialConditions = hitTest.GetInitialConditions();
		ball.transform.position = initialConditions.position;
		FlightSimulator instance = Singleton<FlightSimulator>.instance;
		FlightSimulator.SequenceSimulationParams sequenceSimulationParams = default(FlightSimulator.SequenceSimulationParams);
		sequenceSimulationParams.startParams = initialConditions;
		sequenceSimulationParams.flightToSymulateWith = hitTest.GetUsedBallFlight();
		sequenceSimulationParams.deltaTime = hitTest.symDeltaTime;
		sequenceSimulationParams.record = true;
		sequenceSimulationParams.maxHops = 3;
		sequenceSimulationParams.maxIterations = 100;
		FlightSimulator.SequenceSimulationParams sim = sequenceSimulationParams;
		instance.FillFlightSequence(ball.flightSequence, sim);
		ball.flightSequence.Reset();
		CalculateHitPoint();
	}

	public void CalculateHitPoint()
	{
		KineticPlan.HitPoint hitPoint = KineticPlan.FindHitPointMinimizeZ(ball, base.transform.position.z, Time.fixedDeltaTime, hitAnim, base.transform.position);
		if (hitPoint.foundHitPosition)
		{
			HitBall(hitPoint.maxPosition, ball.flightSequence, hitPoint.stage.startTime + hitPoint.maxTime, hitPoint.maxTime);
		}
	}

	public void HitBall(Vector3 hitPosition, BallFlight hitFlight, float hitTime, float hitTimeInFinalSegment)
	{
		float crossFadeDuration = 0.05f;
		HitAnimationInfo hitAnimationInfo = hitAnim;
		Vector3 vector = (hitPosition - hitAnimationInfo.hitPosition).OnGround();
		KineticPlan.AnimSearchSolution animSearchSolution = FindSolutionToPosition(vector);
		bool flag = true;
		Vector3 startPosition = animSearchSolution.startPosition;
		Quaternion startRotation = animSearchSolution.startRotation;
		float totalDuration = animSearchSolution.totalDuration;
		kineticPlan.CancelAllPendingElements();
		totalDuration += hitAnimationInfo.hitTime;
		float num = 1f;
		float num2 = 1f;
		float num3 = hitTime - hitAnimationInfo.hitTime;
		float num4 = 2.5f;
		if (totalDuration > hitTime)
		{
			float num5 = (totalDuration - hitAnimationInfo.hitTime) / (hitTime - hitAnimationInfo.hitTime);
			Debug.Log("Move only speed " + num5);
			if (hitTime - hitAnimationInfo.hitTime > 0f && num5 <= num4)
			{
				num = num5;
			}
			else
			{
				num = totalDuration / hitTime;
				num2 = num;
			}
		}
		if (!instantMove)
		{
			Debug.Log("Animator speed " + num + " hit speed " + num2);
			if (num > num4)
			{
				return;
			}
			foreach (MoveAnimationInfo anim in animSearchSolution.animList)
			{
				KineticElementMove kineticElementMove = new KineticElementMove();
				kineticElementMove.animInfo = anim;
				if (flag)
				{
					kineticElementMove.startPosition = animSearchSolution.startPosition;
					kineticElementMove.startRotation = animSearchSolution.startRotation;
					flag = false;
				}
				else
				{
					kineticElementMove.startFromCurrentPosition = true;
				}
				kineticElementMove.animatorSpeed = num;
				kineticElementMove.crossFadeDuration = crossFadeDuration;
				startPosition += startRotation * (anim.positionChange + anim.GetAdjustVector(animSearchSolution.xAdjust, animSearchSolution.zAdjust));
				startRotation *= anim.rotationChange;
				kineticElementMove.useDesiredEnd = true;
				kineticElementMove.desiredEndPosition = startPosition;
				kineticPlan.AddElement(kineticElementMove);
			}
		}
		base.transform.position = animSearchSolution.startPosition;
		KineticElementHit kineticElementHit = new KineticElementHit();
		kineticElementHit.animInfo = hitAnimationInfo;
		kineticElementHit.useIK = true;
		kineticElementHit.animatorSpeed = num2;
		kineticElementHit.crossFadeDuration = crossFadeDuration;
		kineticElementHit.hitPosition = hitPosition;
		kineticElementHit.trackFlight = hitFlight;
		kineticElementHit.hitTime = hitTimeInFinalSegment;
		kineticElementHit.flightTimeWhenHit = hitTime;
		kineticElementHit.startFromCurrentPosition = true;
		kineticElementHit.useDesiredEnd = true;
		kineticElementHit.desiredEndPosition = vector + startRotation * hitAnimationInfo.positionChange;
		kineticElementHit.onHitDelegate = OnHitDelegate;
		kineticPlan.AddElement(kineticElementHit);
	}

	private KineticPlan.AnimSearchSolution FindSolutionToPosition(Vector3 position)
	{
		KineticPlan.SearchParams searchParams = default(KineticPlan.SearchParams);
		searchParams.startPos = start.position;
		searchParams.startRot = start.rotation;
		searchParams.endPos = position;
		searchParams.maxDepth = 5;
		searchParams.hitAnimation = hitAnim;
		KineticPlan.SearchParams p = searchParams;
		return kineticPlan.FindPathToGetToPosition(p);
	}

	public void Update()
	{
		Time.timeScale = timeScale;
	}

	public void LateUpdate()
	{
		KineticElementHit kineticElementHit = kineticPlan.activeElement as KineticElementHit;
		if (kineticElementHit != null && kineticElementHit.isActive && Time.timeScale != 0f)
		{
			Animator component = GetComponent<Animator>();
			float num = component.GetCurrentAnimatorStateInfo(0).normalizedTime * kineticElementHit.hitInfo.clipLength;
			num = kineticElementHit.ellapsedTime;
			prevRacketCenter = racketCenter.position;
			prevTime = num;
		}
	}

	private void OnHitDelegate(KineticElementHit hit)
	{
		realHitPoint = racketCenter.position;
		Vector3 vector = hit.startPosition + hit.startRotation * hit.hitInfo.hitPosition;
		Vector3 vector2 = hit.hitPosition - vector;
		calculatedHitPoint = hit.hitPosition;
		Debug.Log("Distance " + Vector3.Distance(realHitPoint, calculatedHitPoint));
		Vector3 vector3 = Quaternion.Inverse(hit.startRotation) * (realHitPoint - hit.startPosition);
		Debug.Log(string.Concat("Hit Point ", vector3, " hit offset distance ", Vector3.Distance(vector3, hit.hitInfo.hitPosition)));
		Debug.Log("time distance " + (hit.flightTimeWhenHit - ball.flightSequence.flightTime));
		FlightSequence flightSequence = ball.flightSequence;
		Vector3 hitVelocity = flightSequence.Velocity();
		hitVelocity.z = -3f * hitVelocity.z;
		hitVelocity.y = 3f * Mathf.Abs(hitVelocity.y);
		HitBall(calculatedHitPoint, hitVelocity, 0f);
		Debug.Break();
	}
}
